#include "sensorviewerpc.h"
#include "dataviewer.h"
#include <QNetworkInterface>
#include <QMessageBox>
#include <QBitmap>
SensorViewerPC::SensorViewerPC(QWidget *parent)
: QMainWindow(parent), viewers(), server(this)
{
	setupUi(this);
	initMap();	
 	server.start();
	connect(act_exit, SIGNAL(triggered()), this, SLOT(closeMainWin()));
	connect(act_about, SIGNAL(triggered()), this, SLOT(aboutApp()));
	connect(act_accelerometer, SIGNAL(triggered()), this, SLOT(openAccelerometer()));
	connect(act_ambient_temperature, SIGNAL(triggered()), this, SLOT(openTemperature()));
	connect(act_gravity, SIGNAL(triggered()), this, SLOT(openGravity()));
	connect(act_gyroscope, SIGNAL(triggered()), this, SLOT(openGyroscope()));
	connect(act_light, SIGNAL(triggered()), this, SLOT(openLight()));
	connect(act_linear_acceleration, SIGNAL(triggered()), this, SLOT(openLinearAcceleration()));
	connect(act_magnetic_field, SIGNAL(triggered()), this, SLOT(openMagnetic()));
	connect(act_orientation, SIGNAL(triggered()), this, SLOT(openOrientation()));
	connect(act_pressure, SIGNAL(triggered()), this, SLOT(openPressure()));
	connect(act_proximity, SIGNAL(triggered()), this, SLOT(openProximity()));
	connect(act_relative_humidity, SIGNAL(triggered()), this, SLOT(openHumidity()));
	connect(act_rotation_vector, SIGNAL(triggered()), this, SLOT(openRotationVector()));
 	label_local_ip->setText(label_local_ip->text() + getLocalIP());
}

void SensorViewerPC::aboutApp()
{
	QString title = QApplication::tr("about");
	QString step1 = QApplication::tr("step1");
	QString step2 = QApplication::tr("step2");
	QString step3 = QApplication::tr("step3");
	QString step4 = QApplication::tr("step4");
	QString step5 = QApplication::tr("step5");
	QString step6 = QApplication::tr("step6");
	QString attention1 = QApplication::tr("attention1");
	QString attention2 = QApplication::tr("attention2");
	QString attention3 = QApplication::tr("attention3");
	QString attention4 = QApplication::tr("attention4");
	QString signature = QApplication::tr("signature");
	QIcon icon_sensor(":/images/sensor.png");
	QMessageBox about_msg(this);
	about_msg.setWindowTitle(title);
	about_msg.setText(step1+"\n"+
		step2 + "\n" + 
		step3 + "\n" + 
		step4 + "\n" + 
		step5 + "\n" + 
		step6 + "\n" + 
		" " + "\n" +
		attention1 + "\n" +
		attention2 + "\n" +
		attention3 + "\n" +
		attention4 + "\n" +
		" " + "\n" + 
		" " + "\n" +
		signature);
	about_msg.setWindowIcon(icon_sensor);
	about_msg.exec();
}
QString SensorViewerPC::getLocalIP()
{
	QString ip;
	QList<QNetworkInterface> list = QNetworkInterface::allInterfaces();
	foreach(QNetworkInterface interface, list)
	{
		QList<QNetworkAddressEntry> entryList = interface.addressEntries(); 
		foreach(QNetworkAddressEntry entry, entryList)
		{
			if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol&&
				entry.prefixLength() > 0 &&
				entry.ip().toIPv4Address() != 2130706433)
			{
				ip = entry.ip().toString();
				return ip;
			}
		}
	}
	return QString();
}
void SensorViewerPC::openAccelerometer()
{
	int num_plot = 3;
	QString name("ACCE");
	if (viewers[name])
		return;
	DataViewer* viewer = new DataViewer(name, num_plot);
	viewer->setWindowTitle(QApplication::tr("Accelerometer"));
	QStringList plot_titles;
	plot_titles.append(QApplication::tr("X Axis Acceleration(m/s^2)"));
	plot_titles.append(QApplication::tr("Y Axis Acceleration(m/s^2)"));
	plot_titles.append(QApplication::tr("Z Axis Acceleration(m/s^2)"));
	viewer->setPlotTitle(plot_titles);
	viewer->setValueTitle(plot_titles);
	QString y_title("m/s^2");
	viewer->setYAxisTitle(y_title);
	central_w->addSubWindow(viewer);
	server.setDataType(name.toLatin1(), num_plot, viewer);
	viewers[name] = viewer;
    connect(viewer, SIGNAL(winClose(const QString&)), this, SLOT(subWinClose(const QString&)));
	viewer->show();
}
void SensorViewerPC::openGravity()
{
	int num_plot = 3;
	QString name("GRAV");
	if (viewers[name])
		return;
	DataViewer* viewer = new DataViewer(name, num_plot);
	viewer->setWindowTitle(QApplication::tr("Gravity"));
	QStringList plot_titles;
	plot_titles.append(QApplication::tr("X Axis Acceleration(m/s^2)"));
	plot_titles.append(QApplication::tr("Y Axis Acceleration(m/s^2)"));
	plot_titles.append(QApplication::tr("Z Axis Acceleration(m/s^2)"));
	viewer->setPlotTitle(plot_titles);
	viewer->setValueTitle(plot_titles);
	QString y_title("m/s^2");
	viewer->setYAxisTitle(y_title);
	central_w->addSubWindow(viewer);
	server.setDataType(name.toLatin1(), num_plot, viewer);
	viewers[name] = viewer;
    connect(viewer, SIGNAL(winClose(const QString&)), this, SLOT(subWinClose(const QString&)));
	viewer->show();
}
void SensorViewerPC::openGyroscope()
{
	int num_plot = 3;
	QString name("GYRO");
	if (viewers[name])
		return;
	DataViewer* viewer = new DataViewer(name, num_plot);
	viewer->setWindowTitle(QApplication::tr("Gyroscope"));
	QStringList plot_titles;
	plot_titles.append(QApplication::tr("X Axis Angular Velocity(rad/s)"));
	plot_titles.append(QApplication::tr("Y Axis Angular Velocity(rad/s)"));
	plot_titles.append(QApplication::tr("Z Axis Angular Velocity(rad/s)"));
	viewer->setPlotTitle(plot_titles);
	viewer->setValueTitle(plot_titles);
	QString y_title("rad/s");
	viewer->setYAxisTitle(y_title);
	central_w->addSubWindow(viewer);
	server.setDataType(name.toLatin1(), num_plot, viewer);
	viewers[name] = viewer;
    connect(viewer, SIGNAL(winClose(const QString&)), this, SLOT(subWinClose(const QString&)));
	viewer->show();
}
void SensorViewerPC::openHumidity()
{
	int num_plot = 1;
	QString name("HUMI");
	if (viewers[name])
		return;
	DataViewer* viewer = new DataViewer(name, num_plot);
	viewer->setWindowTitle(QApplication::tr("Relative Humidity"));
	QStringList plot_titles;
	plot_titles.append(QApplication::tr("Relative Air Humidity(%)"));
	viewer->setPlotTitle(plot_titles);
	viewer->setValueTitle(plot_titles);
	QString y_title("%");
	viewer->setYAxisTitle(y_title);
	central_w->addSubWindow(viewer);
	server.setDataType(name.toLatin1(), num_plot, viewer);
	viewers[name] = viewer;
    connect(viewer, SIGNAL(winClose(const QString&)), this, SLOT(subWinClose(const QString&)));
	viewer->show();
}
void SensorViewerPC::openLight()
{
	int num_plot = 1;
	QString name("LIGH");
	if (viewers[name])
		return;
	DataViewer* viewer = new DataViewer(name, num_plot);
	viewer->setWindowTitle(QApplication::tr("Light"));
	QStringList plot_titles;
	plot_titles.append(QApplication::tr("Ambient Light(lux)"));
	viewer->setPlotTitle(plot_titles);
	viewer->setValueTitle(plot_titles);
	QString y_title("lux");
	viewer->setYAxisTitle(y_title);
	central_w->addSubWindow(viewer);
	server.setDataType(name.toLatin1(), num_plot, viewer);
	viewers[name] = viewer;
    connect(viewer, SIGNAL(winClose(const QString&)), this, SLOT(subWinClose(const QString&)));
	viewer->show();
};
void SensorViewerPC::openLinearAcceleration()
{
	int num_plot = 3;
	QString name("LINA");
	if (viewers[name])
		return;
	DataViewer* viewer = new DataViewer(name, num_plot);
	viewer->setWindowTitle(QApplication::tr("Linear Acceleration"));
	QStringList plot_titles;
	plot_titles.append(QApplication::tr("X Axis Acceleration(m/s^2)"));
	plot_titles.append(QApplication::tr("Y Axis Acceleration(m/s^2)"));
	plot_titles.append(QApplication::tr("Z Axis Acceleration(m/s^2)"));
	viewer->setPlotTitle(plot_titles);
	viewer->setValueTitle(plot_titles);
	QString y_title("m/s^2");
	viewer->setYAxisTitle(y_title);
	central_w->addSubWindow(viewer);
	server.setDataType(name.toLatin1(), num_plot, viewer);
	viewers[name] = viewer;
    connect(viewer, SIGNAL(winClose(const QString&)), this, SLOT(subWinClose(const QString&)));
	viewer->show();
}
void SensorViewerPC::openMagnetic()
{
	int num_plot = 3;
	QString name("MAGN");
	if (viewers[name])
		return;
	DataViewer* viewer = new DataViewer(name, num_plot);
	viewer->setWindowTitle(QApplication::tr("Magnetic"));
	QStringList plot_titles;
	plot_titles.append(QApplication::tr("X Axis Magnetic Field(uT)"));
	plot_titles.append(QApplication::tr("Y Axis Magnetic Field(uT)"));
	plot_titles.append(QApplication::tr("Z Axis Magnetic Field(uT)"));
	viewer->setPlotTitle(plot_titles);
	viewer->setValueTitle(plot_titles);
	QString y_title("uT");
	viewer->setYAxisTitle(y_title);
	central_w->addSubWindow(viewer);
	server.setDataType(name.toLatin1(), num_plot, viewer);
	viewers[name] = viewer;
    connect(viewer, SIGNAL(winClose(const QString&)), this, SLOT(subWinClose(const QString&)));
	viewer->show();
}
void SensorViewerPC::openOrientation()
{
	int num_plot = 3;
	QString name("ORIE");
	if (viewers[name])
		return;
	DataViewer* viewer = new DataViewer(name, num_plot);
	viewer->setWindowTitle(QApplication::tr("Orientation"));
	QStringList plot_titles;
	plot_titles.append(QApplication::tr("Azimuth(deg)"));
	plot_titles.append(QApplication::tr("Pitch(deg)"));
	plot_titles.append(QApplication::tr("Roll(deg)"));
	viewer->setPlotTitle(plot_titles);
	viewer->setValueTitle(plot_titles);
	QString y_title("deg");
	viewer->setYAxisTitle(y_title);
	central_w->addSubWindow(viewer);
	server.setDataType(name.toLatin1(), num_plot, viewer);
	viewers[name] = viewer;
    connect(viewer, SIGNAL(winClose(const QString&)), this, SLOT(subWinClose(const QString&)));
	viewer->show();
}
void SensorViewerPC::openPressure()
{
	int num_plot = 1;
	QString name("PRES");
	if (viewers[name])
		return;
	DataViewer* viewer = new DataViewer(name, num_plot);
	viewer->setWindowTitle(QApplication::tr("Pressure"));
	QStringList plot_titles;
	plot_titles.append(QApplication::tr("Atmospheric Pressure(hPa)"));
	viewer->setPlotTitle(plot_titles);
	viewer->setValueTitle(plot_titles);
	QString y_title("hPa");
	viewer->setYAxisTitle(y_title);
	central_w->addSubWindow(viewer);
	server.setDataType(name.toLatin1(), num_plot, viewer);
	viewers[name] = viewer;
    connect(viewer, SIGNAL(winClose(const QString&)), this, SLOT(subWinClose(const QString&)));
	viewer->show();
}
void SensorViewerPC::openProximity()
{
	int num_plot = 1;
	QString name("PROX");
	if (viewers[name])
		return;
	DataViewer* viewer = new DataViewer(name, num_plot);
	viewer->setWindowTitle(QApplication::tr("Proximity"));
	QStringList plot_titles;
	plot_titles.append(QApplication::tr("Distance(cm)"));
	viewer->setPlotTitle(plot_titles);
	viewer->setValueTitle(plot_titles);
	QString y_title("cm");
	viewer->setYAxisTitle(y_title);
	central_w->addSubWindow(viewer);
	server.setDataType(name.toLatin1(), num_plot, viewer);
	viewers[name] = viewer;
    connect(viewer, SIGNAL(winClose(const QString&)), this, SLOT(subWinClose(const QString&)));
	viewer->show();
}
void SensorViewerPC::openRotationVector()
{
	int num_plot = 3;
	QString name("ROTV");
	if (viewers[name])
		return;
	DataViewer* viewer = new DataViewer(name, num_plot);
	viewer->setWindowTitle(QApplication::tr("Rotation Vector"));
	QStringList plot_titles;
	plot_titles.append(QApplication::tr("x*sin(theta/2)"));
	plot_titles.append(QApplication::tr("y*sin(theta/2)"));
	plot_titles.append(QApplication::tr("z*sin(theta/2)"));
	viewer->setPlotTitle(plot_titles);
	viewer->setValueTitle(plot_titles);
	QString y_title("");
	viewer->setYAxisTitle(y_title);
	central_w->addSubWindow(viewer);
	server.setDataType(name.toLatin1(), num_plot, viewer);
	viewers[name] = viewer;
    connect(viewer, SIGNAL(winClose(const QString&)), this, SLOT(subWinClose(const QString&)));
	viewer->show();
} 
void SensorViewerPC::openTemperature()
{
	int num_plot = 1;
	QString name("TEMP");
	if (viewers[name])
		return;
	DataViewer* viewer = new DataViewer(name, num_plot);
	viewer->setWindowTitle(QApplication::tr("Ambient Temperature"));
	QStringList plot_titles;
	plot_titles.append(QApplication::tr("Temperature(C)"));
	viewer->setPlotTitle(plot_titles);
	viewer->setValueTitle(plot_titles);
	QString y_title("C");
	viewer->setYAxisTitle(y_title);
	central_w->addSubWindow(viewer);
	server.setDataType(name.toLatin1(), num_plot, viewer);
	viewers[name] = viewer;
    connect(viewer, SIGNAL(winClose(const QString&)), this, SLOT(subWinClose(const QString&)));
	viewer->show();
}
void SensorViewerPC::subWinClose(const QString& win_name)
{
	viewers[win_name] = 0;
	server.setDataType(win_name.toLatin1(), 3, 0);
}
bool SensorViewerPC::event(QEvent* e)
{
	switch (e->type())
	{
	case EVENT_TYPE_ONLINE:
		label_is_online->setText(QApplication::tr("online"));
		label_is_online->setStyleSheet("color:green");
		break;
	case EVENT_TYPE_OFFLINE:
		label_is_online->setText(QApplication::tr("offline"));
		label_is_online->setStyleSheet("color:red");
		label_sender_ip->setText(QApplication::tr("Sender IP:"));
		break;
	case EVENT_TYPE_REMOTE_IP:
		label_sender_ip->setText(QApplication::tr("Sender IP:") +
			static_cast<StringEvent*>(e)->str());
		break;
	case EVENT_TYPE_LISTEN_PORT:
		label_local_port->setText(QApplication::tr("Local PORT:") +
			static_cast<StringEvent*>(e)->str());
		break;
	case EVENT_TYPE_TCP_CLOSED:
		server.exit();
		break;
	case EVENT_TYPE_EXIT:
		qApp->exit();
		break;
	default:
		break;
	}
	return QMainWindow::event(e);
}
void SensorViewerPC::closeEvent(QCloseEvent* e)
{
	closeMainWin();
	e->ignore();
}
void SensorViewerPC::closeMainWin()
{
	switch (
		QMessageBox::information(this, QApplication::tr("SensorViewerPC"),
		QApplication::tr("Do you really want to quit?"),
		QApplication::tr("Yes"), QApplication::tr("No"), 0, 1))
	{
	case 0:
		QApplication::postEvent(server.receiver(), new QEvent(EVENT_TYPE_CLOSE_TCP));
		break;
	default:
		break;
	}
}
void SensorViewerPC::initMap()
{
	server.addDataType(QByteArray("ACCE"), 3, 0);
	server.addDataType(QByteArray("TEMP"), 1, 0);
	server.addDataType(QByteArray("GRAV"), 1, 0);
	server.addDataType(QByteArray("GYRO"), 3, 0);
	server.addDataType(QByteArray("LIGH"), 1, 0);
	server.addDataType(QByteArray("LINA"), 3, 0);
	server.addDataType(QByteArray("MAGN"), 3, 0);
	server.addDataType(QByteArray("ORIE"), 3, 0);
	server.addDataType(QByteArray("PRES"), 1, 0);
	server.addDataType(QByteArray("PROX"), 1, 0);
	server.addDataType(QByteArray("HUMI"), 1, 0);
	server.addDataType(QByteArray("ROTV"), 3, 0);

	server.addDataType(QByteArray("HTBT"), 0, (QWidget*)1);

	viewers.insert(QString("ACCE"), 0);
	viewers.insert(QString("TEMP"), 0);
	viewers.insert(QString("GRAV"), 0);
	viewers.insert(QString("GYRO"), 0);
	viewers.insert(QString("LIGH"), 0);
	viewers.insert(QString("LINA"), 0);
	viewers.insert(QString("MAGN"), 0);
	viewers.insert(QString("ORIE"), 0);
	viewers.insert(QString("PRES"), 0);
	viewers.insert(QString("PROX"), 0);
	viewers.insert(QString("HUMI"), 0);
	viewers.insert(QString("ROTV"), 0);
}
SensorViewerPC::~SensorViewerPC()
{

}
